home *** CD-ROM | disk | FTP | other *** search
/ Aminet 52 / Aminet 52 (2002)(GTI - Schatztruhe)[!][Dec 2002].iso / Aminet / dev / c / expat-dev.lha / expat-1.95.5 / xmlwf / xmlmime.c < prev    next >
C/C++ Source or Header  |  2002-07-01  |  3KB  |  164 lines

  1. #include <string.h>
  2. #include "xmlmime.h"
  3.  
  4. static const char *
  5. getTok(const char **pp)
  6. {
  7.   /* inComment means one level of nesting; inComment+1 means two levels etc */
  8.   enum { inAtom, inString, init, inComment };
  9.   int state = init;
  10.   const char *tokStart = 0;
  11.   for (;;) {
  12.     switch (**pp) {
  13.     case '\0':
  14.       if (state == inAtom)
  15.         return tokStart;
  16.       return 0;
  17.     case ' ':
  18.     case '\r':
  19.     case '\t':
  20.     case '\n':
  21.       if (state == inAtom)
  22.         return tokStart;
  23.       break;
  24.     case '(':
  25.       if (state == inAtom)
  26.         return tokStart;
  27.       if (state != inString)
  28.         state++;
  29.       break;
  30.     case ')':
  31.       if (state > init)
  32.         --state;
  33.       else if (state != inString)
  34.         return 0;
  35.       break;
  36.     case ';':
  37.     case '/':
  38.     case '=':
  39.       if (state == inAtom)
  40.         return tokStart;
  41.       if (state == init)
  42.         return (*pp)++;
  43.       break;
  44.     case '\\':
  45.       ++*pp;
  46.       if (**pp == '\0')
  47.         return 0;
  48.       break;
  49.     case '"':
  50.       switch (state) {
  51.       case inString:
  52.         ++*pp;
  53.         return tokStart;
  54.       case inAtom:
  55.         return tokStart;
  56.       case init:
  57.         tokStart = *pp;
  58.         state = inString;
  59.         break;
  60.       }
  61.       break;
  62.     default:
  63.       if (state == init) {
  64.         tokStart = *pp;
  65.         state = inAtom;
  66.       }
  67.       break;
  68.     }
  69.     ++*pp;
  70.   }
  71.   /* not reached */
  72. }
  73.  
  74. /* key must be lowercase ASCII */
  75.  
  76. static int
  77. matchkey(const char *start, const char *end, const char *key)
  78. {
  79.   if (!start)
  80.     return 0;
  81.   for (; start != end; start++, key++)
  82.     if (*start != *key && *start != 'A' + (*key - 'a'))
  83.       return 0;
  84.   return *key == '\0';
  85. }
  86.  
  87. void
  88. getXMLCharset(const char *buf, char *charset)
  89. {
  90.   const char *next, *p;
  91.  
  92.   charset[0] = '\0';
  93.   next = buf;
  94.   p = getTok(&next);
  95.   if (matchkey(p, next, "text"))
  96.     strcpy(charset, "us-ascii");
  97.   else if (!matchkey(p, next, "application"))
  98.     return;
  99.   p = getTok(&next);
  100.   if (!p || *p != '/')
  101.     return;
  102.   p = getTok(&next);
  103. #if 0
  104.   if (!matchkey(p, next, "xml") && charset[0] == '\0')
  105.     return;
  106. #endif
  107.   p = getTok(&next);
  108.   while (p) {
  109.     if (*p == ';') {
  110.       p = getTok(&next);
  111.       if (matchkey(p, next, "charset")) {
  112.         p = getTok(&next);
  113.         if (p && *p == '=') {
  114.           p = getTok(&next);
  115.           if (p) {
  116.             char *s = charset;
  117.             if (*p == '"') {
  118.               while (++p != next - 1) {
  119.                 if (*p == '\\')
  120.                   ++p;
  121.                 if (s == charset + CHARSET_MAX - 1) {
  122.                   charset[0] = '\0';
  123.                   break;
  124.                 }
  125.                 *s++ = *p;
  126.               }
  127.               *s++ = '\0';
  128.             }
  129.             else {
  130.               if (next - p > CHARSET_MAX - 1)
  131.                 break;
  132.               while (p != next)
  133.                 *s++ = *p++;
  134.               *s = 0;
  135.               break;
  136.             }
  137.           }
  138.         }
  139.         break;
  140.       }
  141.     }
  142.   else
  143.     p = getTok(&next);
  144.   }
  145. }
  146.  
  147. #ifdef TEST
  148.  
  149. #include <stdio.h>
  150.  
  151. int
  152. main(int argc, char *argv[])
  153. {
  154.   char buf[CHARSET_MAX];
  155.   if (argc <= 1)
  156.     return 1;
  157.   printf("%s\n", argv[1]);
  158.   getXMLCharset(argv[1], buf);
  159.   printf("charset=\"%s\"\n", buf);
  160.   return 0;
  161. }
  162.  
  163. #endif /* TEST */
  164.